const http = require('http')
const fs = require('fs')
const path = require('path')

let chunkStore = {}
http.createServer((req, res) => {
    if (req.url === '/') {
        res.writeHead(200, {
            'content-type': 'text/html;charset=utf-8'
        })
        fs.createReadStream(path.join(__dirname,'./index.html')).pipe(res)
        return
    }
    if (req.url === '/upload') {
        const boundary = req.headers['content-type'].split('; ')[1].replace("boundary=", "")
        let body = []
        req.on('data', (chunk) => {
            body.push(chunk)
        })
        req.on('end', () => {
            const { index, total, content, name,currentSize } = parseFile(boundary, Buffer.concat(body))
            // 标记存储了多少分片
            if (!chunkStore[name]) { chunkStore[name] = 0 } 
            chunkStore[name]++
            // 分片存储
            if (parseInt(total) > parseInt(index)) {
                const chunkPath = path.join(__dirname, './file/' + name + '-' + index)
                fs.writeFileSync(chunkPath, content, { encoding: 'binary' })
            }
            // 最后一个分片，此时需要合并
            if (parseInt(total) == chunkStore[name]) {
                const filePath = path.join(__dirname, './file/' + name)
                fs.open(filePath, 'w',(err,fd)=>{
                    for (let i = 0; i < total; i++) {
                        const chunkPath = path.join(__dirname, './file/' + name + '-' + i)
                        fs.appendFileSync(filePath, fs.readFileSync(chunkPath), { encoding: 'binary' });
                    }
                    delete chunkStore[name]
                })
            }
            res.end('OK')
        })
        return
    }
}).listen(3001)

function parseFile(boundary, buffers) {
    const newSeparator = `--${boundary}` // 开始符
    const endSeparator = `--${boundary}--` // 结束符
    const textFieldReg = /^Content-Disposition\:\sform\-data\;\sname\="([^\"]+)?"$/i; // 匹配文本字段
    const fileFieldReg = /^Content-Disposition\:\sform\-data\;\sname\="([^\"]+)?";\sfilename="([^\"]+)?"$/i; // 匹配文件内容
    const newLine = '\r\n'

    let start = 0
    let next = buffers.indexOf(newSeparator) + newSeparator.length
    const file = {}
    while (start < next) {
        let line = buffers.slice(start, next)
        // 结尾分隔符
        if(line.toString('utf-8') === endSeparator){
            break
        }
        // 截取 Content-Disposition: form-data
        if (line.toString('utf-8') === newSeparator) {
            start = next + 2 // 跳过换行
            next = buffers.slice(start).indexOf(newLine) + start
            line = buffers.slice(start, next).toString('utf-8')

            if(fileFieldReg.test(line)){ // 匹配二进制字段
                start = next + 2 // 跳过换行
                next =  buffers.slice(start).indexOf(newLine) + start
                line = buffers.slice(start, next).toString('utf-8') // Content-Type
                file['Content-Type'] = line.split(': ')[1]
                start = next + 4 // 跳过换行和空白行
                next = buffers.slice(start).indexOf(newSeparator) + start
                file.content = buffers.slice(start, next - 2) // 二进制文件，需要取得末尾换行
            }else if(line.match(textFieldReg)){
                const name = line.match(textFieldReg)[1]
                start = next + 4 // 跳过换行和空白行
                next = buffers.slice(start).indexOf(newLine) + start
                line = buffers.slice(start, next).toString('utf-8')
                file[name] = line
                next += 2
            }
            start = next
            next = buffers.slice(start).indexOf(newLine) + start 
        }
    }
    return file
}
